package com.baijiaoxi.common.model.base.service.base;

import com.baijiaoxi.common.model.base.CommonError;
import com.baijiaoxi.common.model.base.CoreException;
import com.baijiaoxi.common.model.base.model.CoreModel;
import com.baijiaoxi.common.model.base.service.CoreService;
import com.baijiaoxi.common.model.base.service.impl.MultiDBAbstractCoreService;
import com.baijiaoxi.common.model.base.service.interceptor.QueryInterceptor;
import com.baijiaoxi.common.model.query.Page;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

public interface QueryService<E extends CoreModel> extends BaseService<E>, QueryInterceptor<E> {


    @SuppressWarnings("unchecked")
    default Class<E> getEntityClass() {
        Class<E> eClass = getEntityClass(this.getClass().getGenericInterfaces());
        if (eClass == null)
            eClass = getEntityClass(new Type[]{this.getClass().getGenericSuperclass()});
        return eClass;
    }

    private Class<E> getEntityClass(Type[] types) {
        for (int i = 0; i < types.length; i++) {
            if (types[i] instanceof ParameterizedType parameterizedType) {
                if (parameterizedType.getRawType() == CoreService.class) {
                    return (Class<E>) parameterizedType.getActualTypeArguments()[0];
                } else if (parameterizedType.getRawType() == MultiDBAbstractCoreService.class) {
                    return (Class<E>) parameterizedType.getActualTypeArguments()[0];
                }
            }
            break;
        }
        return null;
    }


    default E getById(Serializable id) {
        E query = null;
        try {
            Class<E> entityClass = getEntityClass();
            Constructor<E> constructor = entityClass.getConstructor();
            query = constructor.newInstance();
            query.setId(id);
        } catch (Exception e) {
            throw CoreException.create(CommonError.objectReflectError, e);
        }
        return getOne(query);
    }

    /**
     * 查询对象
     */
    default E getOne(E query) {
        beforeQuery(InterceptorMethod.getOne, query);
        E entity = getMapper().getOne(query);
        if (entity != null) {
            afterQueryOne(query, entity);
        }
        return entity;

    }


    /**
     * 查询对象数量
     */
    default int getCount(E query) {
        beforeQuery(InterceptorMethod.getCount, query);
        return getMapper().getCount(query);

    }


    /**
     * 查询对象列表
     * 不分页
     */
    default List<E> getList(E query) {
        beforeQuery(InterceptorMethod.getList, query);
        List<E> list = getMapper().getList(query);
        if (list != null && !list.isEmpty()) {
            afterQueryList(query, list);
        }
        return list;

    }


    /**
     * 查询对象列表
     * 分页
     */
    default Page<E> getPage(E query, int num, int size) {
        beforeQuery(InterceptorMethod.getPage, query);
        Page<E> pageQuery = new Page<>(num, size);
        beforePageQuery(pageQuery);
        Page<E> page = getMapper().getPage(pageQuery, query);
        afterQueryPage(query, page);
        return page;

    }


}
